#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "ScriptedEscortAI.h"

enum eNessosSpells
{
    SPELL_VICIOUS_REND        = 125624,
    SPELL_GRAPPLING_HOOK      = 125623,
    SPELL_VANISH              = 125632,
    SPELL_SMOKED_BLADE        = 125633,
};

enum eNessosEvents
{
    EVENT_VICIOUS_REND        = 1,
    EVENT_GRAPPLING_HOOK      = 2,
    EVENT_VANISH              = 3,
    EVENT_SMOKED_BLADE        = 4,
};

class mob_nessos_the_oracle : public CreatureScript
{
    public:
        mob_nessos_the_oracle() : CreatureScript("mob_nessos_the_oracle")
        {
        }

        CreatureAI* GetAI(Creature* creature) const
        {
            return new mob_nessos_the_oracleAI(creature);
        }

        struct mob_nessos_the_oracleAI : public ScriptedAI
        {
            mob_nessos_the_oracleAI(Creature* creature) : ScriptedAI(creature)
            {
            }

            EventMap events;

            void Reset()
            {
                events.Reset();

                events.ScheduleEvent(EVENT_VICIOUS_REND,      7000);
                events.ScheduleEvent(EVENT_GRAPPLING_HOOK, 17000);
                events.ScheduleEvent(EVENT_VANISH, 12000);
            }

            void JustDied(Unit* /*killer*/)
            {
            }

            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                events.Update(diff);

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_VICIOUS_REND:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_VICIOUS_REND, false);
                            events.ScheduleEvent(EVENT_VICIOUS_REND,      7000);
                            break;
                        case EVENT_GRAPPLING_HOOK:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_GRAPPLING_HOOK, false);
                            events.ScheduleEvent(EVENT_GRAPPLING_HOOK, 17000);
                            break;
                        case EVENT_VANISH:
                            me->CastSpell(me, SPELL_VANISH, false);
                            events.ScheduleEvent(EVENT_VANISH, 20000);
                            events.ScheduleEvent(EVENT_SMOKED_BLADE, urand(0, 8000));
                            break;
                        case EVENT_SMOKED_BLADE:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_SMOKED_BLADE, false);

                            break;
                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
        };
};

enum eSkiThikSpells
{
    SPELL_BLADE_FURY    = 125370,
    SPELL_TORNADO       = 125398,
    SPELL_TORNADO_DMG   = 131693,
    SPELL_WINDSONG      = 125373,
};

enum eSkiThikEvents
{
    EVENT_BLADE_FURY    = 1,
    EVENT_TORNADO       = 2,
    EVENT_WINDSONG      = 3,
};

class mob_ski_thik : public CreatureScript
{
    public:
        mob_ski_thik() : CreatureScript("mob_ski_thik")
        {
        }

        CreatureAI* GetAI(Creature* creature) const
        {
            return new mob_ski_thikAI(creature);
        }

        struct mob_ski_thikAI : public ScriptedAI
        {
            mob_ski_thikAI(Creature* creature) : ScriptedAI(creature)
            {
            }

            EventMap events;

            void Reset()
            {
                events.Reset();

                events.ScheduleEvent(EVENT_BLADE_FURY,       8000);
                events.ScheduleEvent(EVENT_TORNADO,         40000);
                events.ScheduleEvent(EVENT_WINDSONG,        32000);
            }

            void JustDied(Unit* /*killer*/)
            {
            }

            void JustSummoned(Creature* summon)
            {
                if (summon->GetEntry() == 64267)
                {
                    summon->AddAura(SPELL_TORNADO_DMG, summon);
                    summon->SetReactState(REACT_PASSIVE);
                    summon->GetMotionMaster()->MoveRandom(20.0f);
                }
            }

            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                events.Update(diff);


                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_BLADE_FURY:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_BLADE_FURY, false);
                            events.ScheduleEvent(EVENT_BLADE_FURY,      8000);
                            break;
                        case EVENT_TORNADO:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_TORNADO, false);
                            events.ScheduleEvent(EVENT_TORNADO, 40000);
                            break;
                        case EVENT_WINDSONG:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_WINDSONG, false);
                            events.ScheduleEvent(EVENT_WINDSONG, 32000);
                            break;

                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
        };
};

enum eHavakSpells
{
    SPELL_DEVASTATING_ARC      = 124946,
    SPELL_SUMMON_QUILEN        = 124980,
    SPELL_TITANIC_STRENGH      = 124976
};

enum eHavakEvents
{
    EVENT_DEVASTATING_ARC       = 1,
    EVENT_SUMMON_QUILEN         = 2,
    EVENT_TITANIC_STRENGH       = 3
};

class mob_havak : public CreatureScript
{
    public:
        mob_havak() : CreatureScript("mob_havak")
        {
        }

        CreatureAI* GetAI(Creature* creature) const
        {
            return new mob_havakAI(creature);
        }

        struct mob_havakAI : public ScriptedAI
        {
            mob_havakAI(Creature* creature) : ScriptedAI(creature)
            {
            }

            EventMap events;

            void Reset()
            {
                events.Reset();

                events.ScheduleEvent(EVENT_DEVASTATING_ARC,   50000);
                events.ScheduleEvent(EVENT_SUMMON_QUILEN,     15000);
                events.ScheduleEvent(EVENT_TITANIC_STRENGH,   32000);
            }

            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                events.Update(diff);

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_DEVASTATING_ARC:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_DEVASTATING_ARC, false);
                            events.ScheduleEvent(EVENT_DEVASTATING_ARC,      50000);
                            break;
                        case EVENT_SUMMON_QUILEN:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_SUMMON_QUILEN, false);
                            events.ScheduleEvent(EVENT_SUMMON_QUILEN, 80000);
                            break;
                        case EVENT_TITANIC_STRENGH:
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
                                me->CastSpell(target, SPELL_TITANIC_STRENGH, false);
                            events.ScheduleEvent(EVENT_TITANIC_STRENGH, 40000);
                            break;

                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
        };
};

enum eMogujiaSoulCallerSpells
{
    SPELL_DRAIN_LIFE        =  84533,
    SPELL_SHADOW_BOLT       =   9613,
    SPELL_SHADOW_CRASH      = 129132
};

enum eMogujiaSoulCallerEvents
{
    EVENT_DRAIN_LIFE        = 1,
    EVENT_SHADOW_BOLT       = 2,
    EVENT_SHADOW_CRASH      = 3
};

class mob_mogujia_soul_caller : public CreatureScript
{
    public:
        mob_mogujia_soul_caller() : CreatureScript("mob_mogujia_soul_caller")
        {
        }

        CreatureAI* GetAI(Creature* creature) const
        {
            return new mob_mogujia_soul_callerAI(creature);
        }

        struct mob_mogujia_soul_callerAI : public ScriptedAI
        {
            mob_mogujia_soul_callerAI(Creature* creature) : ScriptedAI(creature)
            {
            }

            EventMap events;

            void Reset()
            {
                events.Reset();

                events.ScheduleEvent(EVENT_DRAIN_LIFE,      20000);
                events.ScheduleEvent(EVENT_SHADOW_BOLT,     15000);
                events.ScheduleEvent(EVENT_SHADOW_CRASH,    32000);
            }

            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                events.Update(diff);

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_DRAIN_LIFE:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_DRAIN_LIFE, false);
                            events.ScheduleEvent(EVENT_DRAIN_LIFE,      20000);
                            break;
                        case EVENT_SHADOW_BOLT:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_SHADOW_BOLT, false);
                            events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
                            break;
                        case EVENT_SHADOW_CRASH:
                            if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
                                me->CastSpell(target, SPELL_SHADOW_CRASH, false);
                            events.ScheduleEvent(EVENT_SHADOW_CRASH, 32000);
                            break;
                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
        };
};

enum eQuilenStonemawSpells
{
    SPELL_UNSTABLE_SERUM        =  127373,
};

enum eQuilenStonemawEvents
{
    EVENT_UNSTABLE_SERUM        = 1,
};

class mob_quilen_stonemaw : public CreatureScript
{
    public:
        mob_quilen_stonemaw() : CreatureScript("mob_quilen_stonemaw")
        {
        }

        CreatureAI* GetAI(Creature* creature) const
        {
            return new mob_quilen_stonemawAI(creature);
        }

        struct mob_quilen_stonemawAI : public ScriptedAI
        {
            mob_quilen_stonemawAI(Creature* creature) : ScriptedAI(creature)
            {
            }

            EventMap events;

            void Reset()
            {
                events.Reset();
                events.ScheduleEvent(EVENT_UNSTABLE_SERUM,      5000);
            }

            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                events.Update(diff);

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_UNSTABLE_SERUM:
                            if (Unit* target = me->SelectNearestTarget(5.0f))
                                me->CastSpell(target, SPELL_UNSTABLE_SERUM, false);
                            events.ScheduleEvent(EVENT_UNSTABLE_SERUM,      5000);
                            break;

                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
        };
};

enum eZaiTheOutcastSpells
{
    SPELL_RAIN_DANCE    = 124860,
    SPELL_TORRENT       = 124935,
    SPELL_WATER_BOLT    = 124854,
};

enum eZaiTheOutcastEvents
{
    EVENT_RAIN_DANCE    = 1,
    EVENT_TORRENT       = 2,
    EVENT_WATER_BOLT    = 3,
};

class mob_zai_the_outcast : public CreatureScript
{
    public:
        mob_zai_the_outcast() : CreatureScript("mob_zai_the_outcast")
        {
        }

        CreatureAI* GetAI(Creature* creature) const
        {
            return new mob_zai_the_outcastAI(creature);
        }

        struct mob_zai_the_outcastAI : public ScriptedAI
        {
            mob_zai_the_outcastAI(Creature* creature) : ScriptedAI(creature)
            {
            }

            EventMap events;

            void Reset()
            {
                events.Reset();

                events.ScheduleEvent(EVENT_RAIN_DANCE,       8000);
                events.ScheduleEvent(EVENT_TORRENT,         40000);
                events.ScheduleEvent(EVENT_WATER_BOLT,      32000);
            }

            void JustDied(Unit* /*killer*/)
            {
            }

            void JustSummoned(Creature* summon)
            {
                if (summon->GetEntry() == 64267)
                {
                    summon->AddAura(SPELL_TORNADO_DMG, summon);
                    summon->SetReactState(REACT_PASSIVE);
                    summon->GetMotionMaster()->MoveRandom(20.0f);
                }
            }

            void UpdateAI(const uint32 diff)
            {
                if (!UpdateVictim())
                    return;

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                events.Update(diff);

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_RAIN_DANCE:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_RAIN_DANCE, false);
                            events.ScheduleEvent(EVENT_RAIN_DANCE,      8000);
                            break;
                        case EVENT_TORRENT:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_TORRENT, false);
                            events.ScheduleEvent(EVENT_TORRENT, 40000);
                            break;
                        case EVENT_WATER_BOLT:
                            if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO))
                                me->CastSpell(target, SPELL_WATER_BOLT, false);
                            events.ScheduleEvent(EVENT_WATER_BOLT, 32000);
                            break;

                        default:
                            break;
                    }
                }

                DoMeleeAttackIfReady();
            }
        };
};

class npc_waterspeaker_gorai : public CreatureScript
{
public:
    npc_waterspeaker_gorai() : CreatureScript("npc_waterspeaker_gorai") { }

    CreatureAI* GetAI(Creature* creature) const
    {
        return new npc_waterspeaker_goraiAI(creature);
    }

    struct npc_waterspeaker_goraiAI : public ScriptedAI
    {
        npc_waterspeaker_goraiAI(Creature* creature) : ScriptedAI(creature) { }

        uint32 phase;
        uint32 phaseTimer;
        uint64 playerGUID;

        void Reset()
        {
            phase = 0;
            phaseTimer = 0;
            playerGUID = 0;
        }

        void SummonedCreatureDies(Creature * creature, Unit * killer)
        {
            if (auto swordmistress = GetClosestCreatureWithEntry(me, 59273, 30.f))
            {
                swordmistress->AI()->Talk(0);
                swordmistress->CastSpell(swordmistress, 120138, true);
            }

            phase = 7;
            phaseTimer = 5000;
        }

        void SetGUID(uint64 guid, int32)
        {
            playerGUID = guid;
            phase = 1;
            phaseTimer = 10000;
            Talk(0);
            me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP);
        }

        void UpdateAI(const uint32 diff)
        {
            if (!phase)
                return;

            if (phaseTimer <= diff)
            {
                if (!me->SelectNearestPlayer(40.f))
                    Reset();

                if (phase == 1)
                {
                    Talk(1);
                    phaseTimer = 12000;
                }
                else if (phase == 2)
                {
                    me->CastSpell(me, 119729, true);
                    Talk(2);
                    phaseTimer = 7000;
                }
                else if (phase == 3)
                {
                    Talk(3);
                    phaseTimer = 4000;
                    if (auto player = me->GetPlayer(*me, playerGUID))
                        player->KilledMonsterCredit(61654);
                }
                else if (phase == 4)
                {
                    Talk(4);
                    phaseTimer = 5000;
                    if (auto swordmistress = GetClosestCreatureWithEntry(me, 59273, 30.f))
                        swordmistress->CastSpell(swordmistress, 119542, true);
                }
                else if (phase == 5)
                {
                    Talk(5);
                    if (auto spawn = me->SummonCreature(61530, 1921.28f, 167.02f, 477.382f, 4.82f, TEMPSUMMON_DEAD_DESPAWN, 60000))
                        if (auto player = me->GetPlayer(*me, playerGUID))
                            spawn->AI()->AttackStart(player);
                }
                else if (phase == 6) // We return here - phase is finished when summon is killed
                    return;
                else if (phase == 7)
                {
                    Talk(6, playerGUID);
                    phaseTimer = 6000;
                }
                else if (phase == 8)
                {
                    Talk(7);
                    Reset();
                }

                ++phase;
            }
            else
                phaseTimer -= diff;
        }
    };

    bool OnGossipHello(Player* player, Creature* creature)
    {
        if (creature->IsQuestGiver())
            player->PrepareQuestMenu(creature->GetGUID());

        if (creature->IsVendor())
            player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);

        if (player->GetQuestStatus(30480) == QUEST_STATUS_INCOMPLETE)
            player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "I'm ready. Begin the ritual.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);

        player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
        return true;
    }

    bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
    {
        player->PlayerTalkClass->ClearMenus();
        if (action == GOSSIP_ACTION_INFO_DEF + 1)
        {
            player->KilledMonsterCredit(creature->GetEntry());
            creature->AI()->SetGUID(player->GetGUID(), 0);
            creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER | UNIT_NPC_FLAG_GOSSIP);
            player->CLOSE_GOSSIP_MENU();
        }
        else if (action == GOSSIP_ACTION_TRADE)
            player->GetSession()->SendListInventory(creature->GetGUID());

        return false;
    }
};

// Farmhand Freedom quest
class npc_ordo_overseer : public CreatureScript
{
public:
	npc_ordo_overseer() : CreatureScript("npc_ordo_overseer") { }

	CreatureAI* GetAI(Creature* creature) const
	{
		return new npc_ordo_overseerAI(creature);
	}

	struct npc_ordo_overseerAI : public ScriptedAI
	{
		npc_ordo_overseerAI(Creature* creature) : ScriptedAI(creature) { }

		void Reset()
		{
			events.Reset();
		}

		void EnterCombat(Unit * /*victim*/)
		{
			events.ScheduleEvent(1, urand(5000, 10000));
		}

		void JustDied(Unit * who)
		{
			if (auto player = who->GetCharmerOrOwnerPlayerOrPlayerItself())
				if (player->GetQuestStatus(30571) == QUEST_STATUS_INCOMPLETE)
				{
					std::list<Creature*> clist;
					GetCreatureListWithEntryInGrid(clist, me, 59577, 20.f);
					for (auto slave : clist)
					{
						player->KilledMonsterCredit(slave->GetEntry());
						slave->AI()->Talk(0);
						Position pos;
						slave->GetRandomNearPosition(pos, 30.f);
						slave->GetMotionMaster()->MovePoint(1, pos);
						slave->ForcedDespawn(5000);
					}
				}
		}

		void UpdateAI(const uint32 diff)
		{
			if (!me->GetVictim())
				return;

			events.Update(diff);

			while (uint32 eventId = events.ExecuteEvent())
			{
				switch (eventId)
				{
				case 1:
				{
					DoCastVictim(58504);
					events.RescheduleEvent(1, urand(5000, 10000));
				}

				}
			}
			DoMeleeAttackIfReady();
		}
	private:
		EventMap        events;
	};
};

// Challenge Accepted quest
class go_yaungol_banner : public GameObjectScript
{
public:
    go_yaungol_banner() : GameObjectScript("go_yaungol_banner") { }

    bool OnGossipHello(Player* player, GameObject* go)
    {
        if (player->GetQuestStatus(30514) == QUEST_STATUS_INCOMPLETE)
        {
            if (GetClosestCreatureWithEntry(player, 59483, 30.f))
                return false;

            player->SummonGameObject(59483, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0, 0, 0, 0, 0, 60000);
            if (auto urbataar = player->SummonCreature(59483, 2110.05f, 1182.91f, 476.32f, 0, TEMPSUMMON_TIMED_DESPAWN, 120000))
            {
                urbataar->MonsterYell("Fool! I will crush you!", 0, 0);
                urbataar->AI()->AttackStart(player);
            }
        }
        return true;
    }
};

// Barrels of Fun quest
class npc_explosives_barrel : public CreatureScript
{
public:
    npc_explosives_barrel() : CreatureScript("npc_explosives_barrel") { }

    CreatureAI* GetAI(Creature* creature) const
    {
        return new npc_explosives_barrelAI(creature);
    }

    struct npc_explosives_barrelAI : public ScriptedAI
    {
        npc_explosives_barrelAI(Creature* creature) : ScriptedAI(creature) { }

        uint32 phase;
        uint32 tickTimer;

        void Reset()
        {
            phase = 4;
            tickTimer = 1000;
        }

        void UpdateAI(const uint32 diff)
        {
            if (tickTimer <= diff)
            {
                --phase;
                std::string text = "";
                if (phase == 3)
                    text = "Three...";
                else if (phase == 2)
                    text = "Two...";
                else if (phase == 1)
                    text = "One...";
                else if (phase == 0)
                    text = "Boom";

                if (auto owner = me->GetCharmerOrOwnerPlayerOrPlayerItself())
                {
                    owner->MonsterTextEmote(text, owner->GetGUID(), true);
                    if (phase == 0)
                    {
                        for (int i = 0; i < 4; ++i)
                        {
                            if (auto oilRig = GetClosestCreatureWithEntry(me, 60096, 10.f))
                            {
                                me->CastSpell(me, 46419, true);
                                owner->KilledMonsterCredit(oilRig->GetEntry());
                                me->ForcedDespawn();
                            }
                            else if (auto oilRig = GetClosestCreatureWithEntry(me, 60098, 10.f))
                            {
                                me->CastSpell(me, 46419, true);
                                owner->KilledMonsterCredit(oilRig->GetEntry());
                                me->ForcedDespawn();
                            }
                            else if (auto oilRig = GetClosestCreatureWithEntry(me, 60099, 10.f))
                            {
                                me->CastSpell(me, 46419, true);
                                owner->KilledMonsterCredit(oilRig->GetEntry());
                                me->ForcedDespawn();
                            }
                        }
                    }
                }

                tickTimer = 2000;
            }
            else
                tickTimer -= diff;
        }
    };
};

// Free the Dissenters
class npc_inkgill_dissenter : public CreatureScript
{
public:
    npc_inkgill_dissenter() : CreatureScript("npc_inkgill_dissenter") { }

    bool OnGossipHello(Player* player, Creature* creature)
    {
        if (player->GetQuestStatus(30967) == QUEST_STATUS_INCOMPLETE)
            player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "There's still hope - Gorai is still alive, to the south. Go!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);

        player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
        return true;
    }

    bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
    {
        player->PlayerTalkClass->ClearMenus();
        if (action == GOSSIP_ACTION_INFO_DEF + 1)
        {
            player->KilledMonsterCredit(61481);
            creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
            creature->AI()->Talk(0);
            creature->ForcedDespawn(3000);
            float x, y, z;
            creature->GetClosePoint(x, y, z, creature->GetObjectSize() / 3, 10.f);
            creature->GetMotionMaster()->MovePoint(1, x, y, z);
            player->CLOSE_GOSSIP_MENU();
        }

        return false;
    }
};

void AddSC_kun_lai_summit()
{
    new mob_nessos_the_oracle();
    new mob_ski_thik();
    new mob_havak();
    new mob_mogujia_soul_caller();
    new mob_quilen_stonemaw();
    new mob_zai_the_outcast();
    // Quest scripts
    new npc_waterspeaker_gorai();
    new npc_ordo_overseer();
    new go_yaungol_banner();
    new npc_explosives_barrel();
    new npc_inkgill_dissenter();
}
